home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / DJGOS106.ARJ / EVENT.C < prev    next >
C/C++ Source or Header  |  1992-04-13  |  7KB  |  254 lines

  1. /**
  2.  ** EVENT.C
  3.  **  Handlers and setup stuff for an interrupt-driven mouse and keyboard
  4.  **  event queue mechanism for Turbo C and DJGPP (under MS DOS of course)
  5.  **
  6.  **  Copyright (C) 1992, Csaba Biegl
  7.  **    [820 Stirrup Dr, Nashville, TN, 37221]
  8.  **    [csaba@vuse.vanderbilt.edu]
  9.  **
  10.  **  This program is free software; you can redistribute it and/or modify
  11.  **  it under the terms of the GNU General Public License as published by
  12.  **  the Free Software Foundation.
  13.  **
  14.  **  This program is distributed in the hope that it will be useful,
  15.  **  but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  **  GNU General Public License for more details.
  18.  **
  19.  **  You should have received a copy of the GNU General Public License
  20.  **  along with this program; if not, write to the Free Software
  21.  **  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  22.  **/
  23.  
  24. #ifndef  __TURBOC__
  25. #error     Don't even try to compile it with this compiler
  26. #endif
  27.  
  28. #define FOR_GO32
  29.  
  30. #pragma  inline;
  31.  
  32. #include <stdlib.h>
  33. #include <string.h>
  34. #include <alloc.h>
  35. #include <stdio.h>
  36. #include <time.h>
  37. #include <dos.h>
  38.  
  39. #include "eventque.h"
  40.  
  41. extern int  far _ev_interss;    /* interrupt stack segment */
  42. extern int  far _ev_interds;    /* interrupt data segment */
  43. extern int  far _ev_kbintsp;    /* keyboard interrupt stack */
  44. extern int  far _ev_msintsp;    /* mouse interrupt stack */
  45. extern int  far _ev_kbinter;    /* keyboard interrupt flag */
  46.  
  47. extern void interrupt (* far _ev_oldkbint)(void);
  48.  
  49. extern void far          _ev_mouseint(void);
  50. extern void interrupt _ev_keybdint(void);
  51.  
  52. static void dummydraw(void) {}
  53.  
  54. static EventQueue *queue = NULL;
  55. static void (*mousedraw)(void) = dummydraw;
  56. static char *stack = NULL;
  57. static char *qsave = NULL;
  58.  
  59. static int  ms_xpos;
  60. static int  ms_ypos;
  61. static int  ms_xmickey;
  62. static int  ms_ymickey;
  63. static int  first_call = 1;
  64.  
  65. #ifdef FOR_GO32
  66. static int  my_master_pic;
  67. static int  my_new_pic;
  68. #endif
  69.  
  70. #define MS_ENABLE   EVENT_ENABLE(EVENT_MOUSE)
  71. #define KB_ENABLE   EVENT_ENABLE(EVENT_KEYBD)
  72.  
  73. #define KB_SSIZE    128        /* keyboard handler stack size */
  74. #define MS_SSIZE    128        /* mouse handler MINIMAL stack size */
  75.  
  76. #define IABS(x)        (((x) > 0) ? (x) : -(x))
  77.  
  78. void far _ev_mousehandler(int msk,int btn,int mx,int my)
  79. {
  80.     EventRecord *ep;
  81.     int moved = 0;
  82.     int diff;
  83.  
  84.     if((diff = mx - ms_xmickey) != 0) {
  85.         ms_xmickey += diff;
  86.         ms_xpos    += diff;
  87.         if((diff = ms_xpos / queue->evq_xspeed) != 0) {
  88.         ms_xpos %= queue->evq_xspeed;
  89.         if(IABS(diff) >= queue->evq_thresh) diff *= queue->evq_accel;
  90.         diff += queue->evq_xpos;
  91.         if(diff <= queue->evq_xmin) diff = queue->evq_xmin;
  92.         if(diff >= queue->evq_xmax) diff = queue->evq_xmax;
  93.         if(diff != queue->evq_xpos) {
  94.             queue->evq_xpos  = diff;
  95.             queue->evq_moved = moved = 1;
  96.         }
  97.         }
  98.     }
  99.     if((diff = my - ms_ymickey) != 0) {
  100.         ms_ymickey += diff;
  101.         ms_ypos    += diff;
  102.         if((diff = ms_ypos / queue->evq_yspeed) != 0) {
  103.         ms_ypos %= queue->evq_yspeed;
  104.         if(IABS(diff) >= queue->evq_thresh) diff *= queue->evq_accel;
  105.         diff += queue->evq_ypos;
  106.         if(diff <= queue->evq_ymin) diff = queue->evq_ymin;
  107.         if(diff >= queue->evq_ymax) diff = queue->evq_ymax;
  108.         if(diff != queue->evq_ypos) {
  109.             queue->evq_ypos  = diff;
  110.             queue->evq_moved = moved = 1;
  111.         }
  112.         }
  113.     }
  114.     if((msk & ~1) && (queue->evq_enable & MS_ENABLE)) {
  115.         disable();
  116.         ep = &queue->evq_events[queue->evq_wrptr];
  117.         if(++queue->evq_wrptr == queue->evq_maxsize)
  118.         queue->evq_wrptr = 0;
  119.         if(queue->evq_cursize < queue->evq_maxsize)
  120.         queue->evq_cursize++;
  121.         else if(++queue->evq_rdptr == queue->evq_maxsize)
  122.         queue->evq_rdptr = 0;
  123.         enable();
  124.         _AX = 0x200;
  125.         geninterrupt(0x16);
  126.         ep->evt_kbstat = _AL;
  127.         ep->evt_type   = EVENT_MOUSE;
  128.         ep->evt_mask   = msk;
  129.         ep->evt_button = btn;
  130.         ep->evt_xpos   = queue->evq_xpos;
  131.         ep->evt_ypos   = queue->evq_ypos;
  132.         ep->evt_time   = clock();
  133.     }
  134.     if(moved && queue->evq_drawmouse) (*mousedraw)();
  135. }
  136.  
  137. void far _ev_keybdhandler(void)
  138. {
  139.     EventRecord *ep;
  140.     int keycode;
  141.  
  142.     if(queue->evq_enable & KB_ENABLE) for( ; ; ) {
  143.         _AX = 0x100;
  144.         geninterrupt(0x16);
  145.         asm jnz  charpresent;
  146.         return;
  147.       charpresent:
  148.         keycode = (_AL != 0) ? _AL : _AH + 0x100;
  149.         if(queue->evq_delchar) {
  150.         _AX = 0;
  151.         geninterrupt(0x16);
  152.         }
  153.         disable();
  154.         ep = &queue->evq_events[queue->evq_wrptr];
  155.         if(++queue->evq_wrptr == queue->evq_maxsize)
  156.         queue->evq_wrptr = 0;
  157.         if(queue->evq_cursize < queue->evq_maxsize)
  158.         queue->evq_cursize++;
  159.         else if(++queue->evq_rdptr == queue->evq_maxsize)
  160.         queue->evq_rdptr = 0;
  161.         enable();
  162.         _AX = 0x200;
  163.         geninterrupt(0x16);
  164.         ep->evt_kbstat  = _AL;
  165.         ep->evt_keycode = keycode;
  166.         ep->evt_type    = EVENT_KEYBD;
  167.         ep->evt_time    = clock();
  168.     }
  169. }
  170.  
  171. void EventQueueDeInit(void)
  172. {
  173.     if(stack != NULL) {
  174.         _AX = 0;
  175.         geninterrupt(0x33);
  176. #ifdef FOR_GO32
  177.         setvect(my_master_pic+1,_ev_oldkbint);
  178.         if(my_new_pic != my_master_pic) setvect(my_new_pic+1,_ev_oldkbint);
  179. #else
  180.         setvect(9,_ev_oldkbint);
  181. #endif
  182.         free(stack);
  183.         free(qsave);
  184.         stack = NULL;
  185.     }
  186. }
  187.  
  188. #ifdef FOR_GO32
  189. EventQueue *EventQueueInit
  190.   (int qsize,int ms_stksize,void (*msdraw)(void),int master_pic,int new_pic)
  191. #else
  192. EventQueue *EventQueueInit(int qsize,int ms_stksize,void (*msdraw)(void))
  193. #endif
  194. {
  195.     if(stack != NULL) EventQueueDeInit();
  196.     if(qsize < 20) qsize = 20;
  197.     if(ms_stksize < MS_SSIZE) ms_stksize = MS_SSIZE;
  198.     stack = malloc(KB_SSIZE + ms_stksize);
  199.     qsave = malloc(sizeof(EventQueue)+(sizeof(EventRecord)*(qsize-1))+4);
  200.     if((stack == NULL) || (qsave == NULL)) {
  201.         if(stack != NULL) { free(stack); stack = NULL; }
  202.         if(qsave != NULL) { free(qsave); qsave = NULL; }
  203.         return(NULL);
  204.     }
  205.     _ev_interds = FP_SEG(&ms_xpos);
  206.     _ev_interss = FP_SEG(stack);
  207.     _ev_kbintsp = FP_OFF(stack) + KB_SSIZE;
  208.     _ev_msintsp = FP_OFF(stack) + KB_SSIZE + ms_stksize;
  209.     _ev_kbinter = (-1);
  210.     ms_xpos = ms_xmickey = 0;
  211.     ms_ypos = ms_ymickey = 0;
  212.     queue = (EventQueue *)(((long)qsave + 3L) & ~3L);
  213.     memset(queue,0,sizeof(EventQueue));
  214.     queue->evq_maxsize   = qsize;
  215.     queue->evq_xmax         = 79;
  216.     queue->evq_ymax         = 24;
  217.     queue->evq_xspeed    = 8;
  218.     queue->evq_yspeed    = 16;
  219.     queue->evq_thresh    = 100;
  220.     queue->evq_accel     = 1;
  221.     queue->evq_delchar   = 1;
  222.     queue->evq_enable    = MS_ENABLE | KB_ENABLE;
  223.     _AX = 0;
  224.     geninterrupt(0x33);
  225.     if(_AX != 0) {
  226.         _AX = 11;
  227.         geninterrupt(0x33);
  228.         mousedraw = (msdraw != NULL) ? msdraw : dummydraw;
  229.         _ES = FP_SEG(_ev_mouseint);
  230.         _DX = FP_OFF(_ev_mouseint);
  231.         _CX = 0xff;
  232.         _AX = 0x0c;
  233.         geninterrupt(0x33);
  234.     }
  235. #ifdef FOR_GO32
  236.     _ev_oldkbint = getvect(master_pic+1);
  237.     setvect(master_pic+1,_ev_keybdint);
  238.     if(new_pic != master_pic) setvect(new_pic+1,_ev_keybdint);
  239. #else
  240.     _ev_oldkbint = getvect(9);
  241.     setvect(9,_ev_keybdint);
  242. #endif
  243.     if(first_call) {
  244. #ifdef FOR_GO32
  245.         my_master_pic = master_pic;
  246.         my_new_pic = new_pic;
  247. #endif
  248.         atexit(EventQueueDeInit);
  249.         first_call = 0;
  250.     }
  251.     return(queue);
  252. }
  253.  
  254.